﻿using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Content;

namespace BaGiaDanhCuop
{
    
    public class Animation
    {
        #region Fields
        // Animation variables
        Texture2D animatedCharacter;
        Point sheetSize;
        public Point currentFrame;
        public Point FrameSize { get; set; }
        public Vector2 Offset;
        public double total = 0;        
        public double[] duration;

        public int FrameCount
        {
            get { return sheetSize.X * sheetSize.Y; }
        }


        /// <summary>
        /// Returns or sets the current animation frame.
        /// </summary>
        public int FrameIndex
        {
            get
            {
                return sheetSize.X * currentFrame.Y + currentFrame.X;
            }
            set
            {
                if (value >= sheetSize.X * sheetSize.Y + 1)
                {
                    throw new InvalidOperationException(
                        "Specified frame index exeeds available frames");
                }
                currentFrame.Y = value / sheetSize.X;
                currentFrame.X = value % sheetSize.X;
            }
        }

        public bool IsActive { get; private set; }
        #endregion

        #region Initialization
        /// <summary>
        /// Constructor of an animation class
        /// </summary>
        /// <param name="frameSheet">Texture with animation frames sheet</param>
        /// <param name="size">Single frame size</param>
        /// <param name="frameSheetSize">The whole frame sheet size</param>
        /// <param name="interval">Interval between progressing to the next frame</param>
        public Animation(Vector2 position, Texture2D frameSheet,Point frameSheetSize)
        {
            this.Offset = position;            
            animatedCharacter = frameSheet;                       
            sheetSize = frameSheetSize;            
            Point size;
            size = new Point();
            size.X = frameSheet.Bounds.Width / frameSheetSize.X;
            size.Y = frameSheet.Bounds.Height / frameSheetSize.Y;                
            FrameSize = size;
            duration = new double[frameSheetSize.X * frameSheetSize.Y];            
        }
        #endregion

        #region Update and Render
        /// <summary>
        /// Updates the animaton progress
        /// </summary>
        public void Update(double delta)
        {
                           
            total += delta;
            if (total < duration[FrameIndex])
                return;
            total = 0;
            if (IsActive)
            {
                if (FrameIndex >= FrameCount - 1)
                {
                   PlayFromFrameIndex(0);
                }
                else
                {
                    // Remember that updating "currentFrame" will also
                    // update the FrameIndex property.

                    currentFrame.X++;
                    if (currentFrame.X >= sheetSize.X)
                    {
                        //System.Windows.MessageBox.Show("dkmm");
                        currentFrame.X = 0;
                        currentFrame.Y++;
                    }
                    if (currentFrame.Y >= sheetSize.Y)
                        currentFrame.Y = 0;
                }
            }
        }

        /// <summary>
        /// Rendering of the animation
        /// </summary>
        /// <param name="spriteBatch">SpriteBatch in which current 
        /// frame will be rendered</param>
        /// <param name="position">The position of current frame</param>
        /// <param name="spriteEffect">SpriteEffect to apply on 
        /// current frame</param>
        public void Draw(SpriteBatch spriteBatch, SpriteEffects spriteEffect)
        {
            Draw(spriteBatch, 1.0f, spriteEffect);
        }

        /// <summary>
        /// Rendering of the animation
        /// </summary>
        /// <param name="spriteBatch">SpriteBatch in which current frame
        /// will be rendered</param>
        /// <param name="position">The position of the current frame</param>
        /// <param name="scale">Scale factor to apply on the current frame</param>
        /// <param name="spriteEffect">SpriteEffect to apply on the 
        /// current frame</param>
        public void Draw(SpriteBatch spriteBatch, float scale, SpriteEffects spriteEffect)
        {
            spriteBatch.Draw
                    (animatedCharacter, Offset, new Rectangle(
                    FrameSize.X * currentFrame.X,
                    FrameSize.Y * currentFrame.Y,
                    FrameSize.X,
                    FrameSize.Y),
                  Color.White, 0f, Vector2.Zero, scale, spriteEffect, 0);
        }

        /// <summary>
        /// Causes the animation to start playing from a specified frame index
        /// </summary>
        /// <param name="frameIndex"></param>
        public void PlayFromFrameIndex(int frameIndex)
        {
            FrameIndex = frameIndex;
            IsActive = true;
        }

        public void animate(double delta) {
            FrameIndex = 0;
            IsActive = true;
            for (int i = 0; i < duration.Length; i++)
                duration[i] = delta;
        }

        public void animate(double[] delta){
            FrameIndex = 0;
            IsActive = true;
            if (delta.Length != duration.Length)
                throw new Exception("Not match frame");
            duration = delta;
        }
       
        #endregion
    }
}
